#coding=utf-8

require "aio/core"
require "rexml/document"

class Aio::Module::InputStyle::CompareXML < Aio::Module::InputStyle
  include Aio::Module
  include REXML
  include Aio::Ui::Verbose

  def initialize
    super({
      :author				=> "Elin",
      :description	=> "这个模块用于分析由output/out_compare_xml模块生成的xml文件",
      :platform			=> "all",
      :file_suffix	=> Regexp.new('\.xml$'),
      :pass_file		=> [],
    })
  end

  def parse
    # dir 为 Pathname 类
    print_good "正在打开文件 #{self.input_file}"
    file = File.open(self.input_file)
    print_good "打开文件完成"
    print_good "正在载入到XML模块..."
    atime = Time.now
    doc = Document.new(file)
    root = doc.root
    print_good "载入完成。载入用时 #{format("%.2fs", Time.now.to_f - atime.to_f)}"
    device_hash = {}

    index = 0
    total = root.elements.size

    print_good "开始比对分析..."
    # 按每台设备解析XML
    root.elements.each do |device|
      index += 1
      info = {}
      device_name = device.attributes['device_name']
      device_hash[device_name] = info

      # 按照每个cmd解析XML
      device.elements.each do |cmd|
        i = {}
        ch = cmd.name
        cmd_name = cmd.attributes['cmd']
        # 当同一个cmd有两个symbol时
        if info[cmd_name].nil?
          info[cmd_name] = {ch.to_sym => i}
        else
          info[cmd_name][ch.to_sym] = i
        end

        # 进度条
        progress_bar(total, index, device_name)

        # 还有一种情况是当<attr cmd='show' val='var'/>
        # 此时就可以直接将val填入
        attr_val = cmd.attributes['val']
        attr_val ? info[cmd_name][ch.to_sym] = attr_val : to_h(cmd, i)
      end
    end

    clear_line
    return device_hash
  end

  def to_h(xml, hash)
    xml.elements.each do |e|
      if e.has_elements?
        son = {}
        hash[convert(e.name)] = son
        to_h(e, son)
      else
        hash[convert(e.name)] = e.attributes['val']
      end
    end
  end

  # 转换恢复会出错字符串
  def convert(e)
    #/__/.match(e) ? e.gsub!('__', '/').to_sym : e.to_sym
    e.gsub!('__', '/') if /__/.match(e)
    e.gsub!('_sp_', ' ') if e.include?('_sp_')
    e.gsub!(/^_i/, '') if /^_i/.match(e)
    e.to_sym
  end
end
